package com.woniuxy.purchase.controller;


import cn.hutool.core.date.DateTime;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.BCrypt;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.woniuxy.model.entity.User;
import com.woniuxy.purchase.entity.dto.DemandDetailsDTO;
import com.woniuxy.purchase.entity.dto.SelectDemandDTO;
import com.woniuxy.purchase.entity.dto.UpDatePasswordDTO;
import com.woniuxy.purchase.entity.pojo.BuyDemand;
import com.woniuxy.purchase.entity.vo.DemandDetailsVO;
import com.woniuxy.purchase.entity.vo.TopDemandVO;
import com.woniuxy.purchase.mapper.BuyDemandMapper;
import com.woniuxy.purchase.mapper.BuyPurchaseMapper;
import com.woniuxy.purchase.service.BuyDemandService;
import com.woniuxy.purchase.service.impl.HotGoodsThread;
import com.woniuxy.purchase.util.MsgUtil;
import com.woniuxy.purchase.util.R;
import com.woniuxy.response.CustomPage;
import com.woniuxy.response.ResponseResult;
import com.woniuxy.service.FeignUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/purchase/buyDemand")
@Slf4j
public class BuyDemandController {
    @Resource
    private BuyDemandMapper buyDemandMapper;
    @Resource
    private RedisTemplate<String,Object> redisTemplate;
    @Resource
    private HotGoodsThread hotGoodsThread;
    @Resource
    private FeignUserService feignUserService;
    @Resource
    private BuyDemandService buyDemandService;

    /**
     * 新增添加需求单并为其添加商品
     * end
     */
    @PostMapping("/insertDemand")
    @PreAuthorize("hasAuthority('buy:addNeed')")
    public R insertDemand(@RequestBody DemandDetailsDTO dto) {
        log.info("开始新增需求单,{}", dto);
        buyDemandService.insertDemand(dto);
        return R.success("新增成功");
    }

    /**
     * 查询状态为1的需求单
     * end
     *
     * @return
     */
    @PostMapping("/findDemandByCondition")
    public R<List<BuyDemand>> findDemandByCondition(@RequestBody(required = false) SelectDemandDTO dto) {
        log.info("按状态查询需求单,{}", dto);
        Page<BuyDemand> page = buyDemandService.findDemandByCondition(dto);
        CustomPage<List<BuyDemand>> customPage = new CustomPage<>();
        //每页多少条数据
        customPage.setSize((int) page.getSize());
        //当前页码
        customPage.setCurrentPage((int) page.getCurrent());
        //总页数
        customPage.setTotalPage((int) page.getPages());
        customPage.setTotal((int) page.getTotal());
        //数据
        List<BuyDemand> records = page.getRecords();
        customPage.setData(records);
        return R.success(customPage);
    }

    /**
     * 根据需求单ID查询包含哪些商品
     * end
     */
    @GetMapping("/findDemandDetails/{id}")
    public R<List<DemandDetailsVO>> findDemandDetails(@PathVariable("id") Integer id) {
        return R.success(buyDemandService.findDemandDetails(id));
    }

    /**
     * 把需求单转为采购单
     * end
     */
    @PreAuthorize("hasAuthority('buy:addBuy')")
    @PostMapping("/demandToPurchase/{id}")
    public R demandToPurchase(@PathVariable("id") Integer id) {
        log.info("开始将需求单转换为采购单,需求单id为{}", id);
        //1.新增采购单
        buyDemandService.demandToPurchase(id);
        return R.success("采购单生成成功");
    }

    /**
     * 修改需求单状态
     * end
     */
    @PreAuthorize("hasAnyAuthority('buy:updateBuy')")
    @PostMapping("/updateDemandStateById/{state}/{id}")
    public R updateDemandStateById(@PathVariable("state") Integer state, @PathVariable("id") Integer id) {
        buyDemandService.updateDemandStateById(state, id);
        return R.success();
    }

    @GetMapping("/findUserByAccount/{account}")
    public R findUserByAccount(@PathVariable("account") String account) {
        ResponseResult<User> result = feignUserService.findUserByAccount(account);
        System.out.println(result.getData());
        boolean b = result
                .getData()
                .getRoleList()
                .stream()
                .anyMatch(role -> role.getPermsList().stream().anyMatch(perms -> perms.getName().equals("buy:agreeBuy")));
        if (!b) {
            return R.error(401, "无权限");
        }
        return R.success();
    }

    @PostMapping("/generateExcel")
    public R generateExcel(@RequestBody List<BuyDemand> list) {
        //通过工具类创建writer
        ExcelWriter writer = ExcelUtil.getWriter("D:\\java\\project\\four\\excel\\需求表.xlsx");
        //跳过当前行，既第一行，非必须，在此演示用
        //writer.passCurrentRow();
        //起别名
        writer.addHeaderAlias("id","单号");
        writer.addHeaderAlias("createUser","创建人");
        writer.addHeaderAlias("createTime","创建时间");
        writer.addHeaderAlias("updateUser","修改人");
        writer.addHeaderAlias("updateTime","修改时间");
        //合并单元格后的标题行，使用默认标题样式
        writer.merge(list.size(), "需求单");
        //排除未起别名的列
        writer.setOnlyAlias(true);
        //一次性写出内容，强制输出标题
        writer.write(list, true);
        //关闭writer，释放内存
        writer.close();

        String account = SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString();
        buyDemandMapper.insertLog(account, DateTime.now().toString(),"需求单");
        //2.想数据库添加日志
        return R.success();
    }

    @GetMapping("/getHotData/{currentDate}")
    public R getHotData(@PathVariable("currentDate") String currentDate){
        return R.success(hotGoodsThread.getHotDateByCurrentDate(currentDate));
    }

    /**
     * 发送验证码
     * @return
     */

    @PostMapping("/sendCode")
    public R sendCode(@RequestBody UpDatePasswordDTO dto) {
        log.info("开始发送验证码,{}",dto);
        dto.setAccount(SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString());
        //1.判断该手机号格式是否正确
        if (!Validator.isMobile(dto.getCellphone())) return R.error(500,"手机号不符合规范");
        //2.检查该账户和绑定的手机号是否对应
        if(buyDemandService.findPhoneByAccount(dto.getCellphone(),dto.getAccount()) != 1)return R.error(400,"该账号未与该手机号绑定");
        //3.判断是否已经发送验证码
        String code = (String) redisTemplate.opsForValue().get(dto.getCellphone());
        //如果获取到,直接返回
        if(!StrUtil.isEmpty(code))  return R.error(411,"验证码已发送,请勿重复发送");

        //4、向阿里云发送验证码
        code = RandomUtil.randomNumbers(6);//生成验证码的随机值
        Map<String,Object> param = new HashMap<>();
        param.put("code", code);
        boolean isSend = MsgUtil.send(param,dto.getCellphone());
        if(isSend) {
            //往redis中设置数据：key、value、过期值、过期时间单位  MINUTES代表分钟
            redisTemplate.opsForValue().set(dto.getCellphone(), code,1, TimeUnit.MINUTES);
            return R.success("验证码发送成功!2分钟内有效,请注意查收");
        } else {
            return R.error(500,"出现未知异常,可能是余额不足");
        }
    }

    @PostMapping("/checkCode")
    public R checkCode(@RequestBody UpDatePasswordDTO dto){
        String o = (String) redisTemplate.opsForValue().get(dto.getCellphone());
        log.info("开始校验验证码以及修改密码,{},{}",o,dto);
        if (o != null && !o.equals(dto.getCode())) {
            return R.error(400, "验证码错误");
        }
        buyDemandService.updatePwdByAccount(dto.getNewPwd(),dto.getAccount());
        return R.success("修改成功,请重新登陆");
    }

    @GetMapping("/getTopDemand")
    public R getTopDemand(){
        List<TopDemandVO> list = buyDemandService.getTopDemand();
        return R.success(list);
    }
}
